package com.sudo.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ProvinceCityUtil {

    /**
     * 建立连接
     * @param url <a href="http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/">...</a>
     */
    private static Document connect(String url) {
        if (url == null || url.isEmpty()) {
            throw new IllegalArgumentException("无效的url");
        }
        try {
            ThreadUtil.sleep(1000);
            return Jsoup.connect(url).timeout(200 * 2000).get();
        } catch (IOException e) {
            log.error("地址异常：{}",url,e);
            return null;
        }
    }

    /**
     * 获取所有的省份
     */
    public static List<SysCity> getProvinces(String url) {
        List<SysCity> sysAreas = new ArrayList<>();
        Document connect = connect(url+"index.html");
        Elements rowProvince = connect.select("tr.provincetr");
        for (Element provinceElement : rowProvince) {
            Elements select = provinceElement.select("a");
            for (Element province : select) {
                String codUrl = province.select("a").attr("href");
                String fatherCode = codUrl.replace(".html", "0000");
                String name = province.text();
                SysCity sysCities = returnCities(fatherCode, name, "0000", "01");
                sysAreas.add(sysCities);
                log.info("++++++++++++++++++++++++++开始获取" + name + "下属市区行政区划信息++++++++++++++++++++++++");
                String provinceUrl = url + codUrl;
                List<SysCity> sysAreasList = getCities(url,provinceUrl, fatherCode);
                if (sysAreasList == null){
                    continue;
                }
                sysAreas.addAll(sysAreasList);

            }
        }
        return sysAreas;
    }


    /**
     * 获取市行政区划信息
     * @param provinceUrl 省份对应的地址
     * @param parentCode  需要爬取的省份行政区划（对于市的父级代码即为省行政区划）
     * @return 城市集合
     */
    public static List<SysCity> getCities(String url,String provinceUrl,String parentCode){
        List<SysCity> sysAreas = new ArrayList<>();
        Document connect = connect(provinceUrl);
        if (connect == null){
            return null;
        }
        Elements rowCity = connect.select("tr.citytr");
        for (Element cityElement : rowCity) {
            String codUrl = cityElement.select("a").attr("href");
            String name = cityElement.select("td").text();
            String[] split = name.split(" ");
            String addrCode = split[0].substring(0,4);
            SysCity sysCities = returnCities(addrCode+"00",split[1],parentCode,"02");
            sysAreas.add(sysCities);
            log.info("-------------------开始获取"+split[1]+"下属区县行政区划信息-----------------------");
            String cityUrl =  url+codUrl;
            List<SysCity> downAreaCodeList = getCounties(cityUrl,addrCode+"00");
            if (downAreaCodeList == null){
                continue;
            }
            sysAreas.addAll(downAreaCodeList);

        }
        return sysAreas;
    }

    /**
     * 获取区县行政区划信息
     * @param cityUrl 城市对应的地址
     * @param parentCode  需要爬取的市行政区划（对于区县的父级代码即为市行政区划）
     * @return 城市集合
     */
    public static List<SysCity> getCounties(String cityUrl,String parentCode){
        List<SysCity> sysAreas = new ArrayList<>();
        Document connect = connect(cityUrl);
        if (connect == null){
            return null;
        }
        Elements rowDown = connect.select("tr.countytr");
        for (Element downElement : rowDown) {
//            String codUrl = downElement.select("a").attr("href");
            String name = downElement.select("td").text();
            String[] split = name.split(" ");
            if(!"市辖区".equals(split[1])){
                SysCity sysCities = returnCities(split[0].substring(0,6),split[1],parentCode,"03");
                sysAreas.add(sysCities);
            }
        }
        return sysAreas;
    }

    /**
     * 返回城市对象  Lock-玄清
     * @param addrCode 城市代码
     * @param addrName 城市名称
     * @param fatherCode 父级代码
     * @return 城市
     */
    private static SysCity returnCities(String addrCode,String addrName,String fatherCode,String type){
        SysCity sysCity = new SysCity();
        sysCity.setAddrCode(addrCode);
        sysCity.setAddrName(addrName);
        sysCity.setFatherCode(fatherCode);
        sysCity.setType(type);
        return sysCity;
    }

    public static class SysCity {
        private String addrCode;
        private String addrName;
        private String fatherCode;
        private String type;

        public String getAddrCode() {
            return addrCode;
        }

        public void setAddrCode(String addrCode) {
            this.addrCode = addrCode;
        }

        public String getAddrName() {
            return addrName;
        }

        public void setAddrName(String addrName) {
            this.addrName = addrName;
        }

        public String getFatherCode() {
            return fatherCode;
        }

        public void setFatherCode(String fatherCode) {
            this.fatherCode = fatherCode;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }
}
